package org.jcc.core.demo.cash;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 可用于换零的零钱列表
 * 基本就是ArrayList的<b>轻量封装</b>，以提供更加贴合<b>领域（Domain）</b>的语义。
 * 
 * @author Golden Shaw
 *
 */
public class CashList {

    private List<Cash> list = new ArrayList<Cash>();
    
    public CashList(Cash ... cashes) {
        if (cashes == null || cashes.length == 0) {
            throw new IllegalArgumentException("请传入至少一个参数！");
        }
        List<Cash> cashList = Arrays.asList(cashes);
        for (Cash cash : cashList) {
            if (!list.contains(cash)) {
                list.add(cash);
            } else {
                throw new  IllegalArgumentException("重复的参数！" + cash);
            }
        }
    }
    
    public boolean containsOnlyOneCash() {
        return list.size() == 1;
    }
    
    public Cash getTheOnlyOneCash() {
        return list.get(0);
    }
    
    /**
     * 获取不带第一个元素的新list
     * 如果当前是[20, 10, 5, 1]，那么将得到[10, 5, 1]
     * @return
     */
    public CashList newCashListWithoutFirstCash() {
        List<Cash> dest = new ArrayList<Cash>(list);
        dest.remove(0);
        
        // new Cash[0] 只是为能推导出泛型类型，本身并无其它意义
        //也可以使用强制类型转换： new CashSet((Cash[]) dest.toArray());
        return new CashList(dest.toArray(new Cash[0]));
    }

    public Cash getFirstCash() {
        return list.get(0);
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        for (int i = 0; i < list.size(); i++) {
            result = prime * result + list.get(i).hashCode();
        }
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        CashList objList = (CashList) obj;
        if (list.size() == objList.list.size()) {
            for (int i = 0; i < list.size(); i++) {
                if (list.get(i).equals(objList.list.get(i))) {
                    continue;
                } else {
                    return false;
                }
            }
            return true;
        } else {
            return false;
        }
    }
    
}
